package com.divillysausages.dsair.log 
{
	import com.divillysausages.dsair.DSAir;
	import flash.display.Shape;
	import flash.events.KeyboardEvent;
	import flash.system.System;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	
	/**
	 * The display object that we can use to show our logs when debugging
	 * @author Damian Connolly
	 */
	public class LogDisplay 
	{
		
		/********************************************************************/
		
		private var m_display:TextField 		= null;	// the display textfield (where we show our logs)
		private var m_instructions:TextField	= null; // the instructions for the controls
		private var m_source:Vector.<LogMsg>	= null; // our source of log messages to display
		private var m_scrollbar:Shape			= null; // the scrollbar to show where we are in our scrolling
		
		/********************************************************************/
		
		/**
		 * Sets the visibility for the log display
		 */
		public function get visible():Boolean { return ( this.m_display.parent != null ); }
		public function set visible( b:Boolean ):void
		{
			if ( b )
				this._activate();
			else
				this._deactivate();
		}
		
		/********************************************************************/
		
		/**
		 * Creates the log display
		 * @param source The source of log messages to display
		 */
		public function LogDisplay( source:Vector.<LogMsg> ) 
		{
			// create the textfields that we'll use
			this._createTextFields();
			
			// create our scrollbar
			this.m_scrollbar 	= new Shape;
			this.m_scrollbar.x	= this.m_display.x + this.m_display.width;
			this.m_scrollbar.y	= this.m_display.y;
			
			// hold our source
			this.m_source = source;
		}
		
		/**
		 * Goes through our logs and updates what we display
		 */
		public function updateDisplay():void
		{
			// clear the previous ones
			this.m_display.text = "";
			
			// display all our logs
			var len:int 		= this.m_source.length;
			var display:String	= "";
			for ( var i:int = 0; i < len; i++ )
				display += this.m_source[i].toHTMLSTring();
				
			// set the text and move to the end
			this.m_display.htmlText = display;
			this.m_display.scrollV	= this.m_display.maxScrollV;
			
			// update our scrollbar
			this._updateScrollbar();
		}
		
		/********************************************************************/
		
		// creates the textfields that we use for the display
		private function _createTextFields():void
		{
			// create our display textfield
			this.m_display 						= new TextField;
			this.m_display.width 				= DSAir.stage.stageWidth * 0.75;
			this.m_display.height				= DSAir.stage.stageHeight * 0.75;
			this.m_display.border				= true;
			this.m_display.background			= true;
			this.m_display.multiline			= true;
			this.m_display.mouseWheelEnabled	= false;
			
			// create our instructions
			var tf:TextFormat 				= new TextFormat( "Trebuchet Ms", 10 );
			this.m_instructions 			= new TextField;
			this.m_instructions.defaultTextFormat = tf;
			this.m_instructions.autoSize 	= TextFieldAutoSize.LEFT;
			this.m_instructions.selectable 	= false;
			this.m_instructions.mouseEnabled = false;
			this.m_instructions.border 		= true;
			this.m_instructions.background 	= true;
			this.m_instructions.text 		= "[Pg Up], [Pg Dn] to move the display up or down, Ctrl+C to copy the log.";
			this.m_instructions.y			= this.m_display.y + this.m_display.height;
		}
		
		// activates the log display, adding it to the stage
		private function _activate():void
		{
			DSAir.stage.addChild( this.m_display );
			DSAir.stage.addChild( this.m_instructions );
			DSAir.stage.addChild( this.m_scrollbar );
			
			// add our key listeners
			DSAir.bindKey( Keyboard.PAGE_UP, this._onPageUp );
			DSAir.bindKey( Keyboard.PAGE_DOWN, this._onPageDown );
			DSAir.bindKey( Keyboard.C, this._onCopy );
			
			// update our display
			this.updateDisplay();
		}
		
		// deactivates the log display, removing it from the stage
		private function _deactivate():void
		{
			// remove it from the stage
			if ( this.m_display.parent != null )
				this.m_display.parent.removeChild( this.m_display );
			if ( this.m_instructions.parent != null )
				this.m_instructions.parent.removeChild( this.m_instructions );
			if ( this.m_scrollbar.parent != null )
				this.m_scrollbar.parent.removeChild( this.m_scrollbar );
			
			// add our key listeners
			DSAir.unbindKey( Keyboard.PAGE_UP );
			DSAir.unbindKey( Keyboard.PAGE_DOWN );
			DSAir.unbindKey( Keyboard.C );
		}
		
		// updates the scrollbar
		private function _updateScrollbar():void
		{
			// clear the previous
			this.m_scrollbar.graphics.clear();
			
			// draw the bg
			this.m_scrollbar.graphics.lineStyle( 1.0 );
			this.m_scrollbar.graphics.beginFill( 0xdddddd );
			this.m_scrollbar.graphics.drawRect( 0.0, 0.0, 5.0, this.m_display.height );
			this.m_scrollbar.graphics.endFill();
			
			// get the bar height
			var barHeight:Number = this.m_display.height;
			if ( this.m_display.maxScrollV > 1 )
				barHeight *= ( this.m_display.numLines - this.m_display.maxScrollV ) / this.m_display.numLines;
				
			// get the max movement dist
			var maxMove:Number = this.m_display.height - barHeight;
			
			// get our y along that
			var y:Number = maxMove * ( ( this.m_display.scrollV - 1 ) / ( this.m_display.maxScrollV - 1 ) );
				
			// draw the bar
			this.m_scrollbar.graphics.beginFill( 0xffffff );
			this.m_scrollbar.graphics.drawRect( 0.0, y, 5.0, barHeight );
			this.m_scrollbar.graphics.endFill();
		}
		
		// called when we press the page up and we're active - move the log up
		private function _onPageUp( e:KeyboardEvent ):void
		{
			// move up
			if ( this.m_display.scrollV > 1 )
			{
				this.m_display.scrollV--;
				this._updateScrollbar();
			}
		}
		
		// called when we press the page down key and we're active - move the log down
		private function _onPageDown( e:KeyboardEvent ):void
		{
			// move down
			if ( this.m_display.scrollV < this.m_display.maxScrollV )
			{
				this.m_display.scrollV++;
				this._updateScrollbar();
			}
		}
		
		// called when we press the c key and we're active - copy the log
		private function _onCopy( e:KeyboardEvent ):void
		{
			if ( e.ctrlKey )
			{
				System.setClipboard( this.m_display.text );
				DSAir.log( this, "Log copied" );
			}
		}
		
	}

}